package tech.powerjob.official.processors.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: 刘志新
 * @email: lzxorz@163.com
 */
public class ProcessUtils {

    public static synchronized String getPid(Process p) {
        String pid = null;
        try {
            if (p.getClass().getName().equals("java.lang.UNIXProcess")) {
                Field f = p.getClass().getDeclaredField("pid");
                f.setAccessible(true);
                pid = String.valueOf(f.getInt(p));
                f.setAccessible(false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pid;
    }

    /**
     * 获取执行命令进程的父子进程ids
     * @author 刘志新
     * @email lzxorz@163.com
     */
    public static List<String> getPids(List<String> runCommands) {
        List<String> result = new ArrayList<>();
        String[] cmds = {"/bin/sh", "-c", "ps -ef | grep \"" + String.join(" ", runCommands) + "\" | grep -v grep | awk '{ print $2 }'"};
        try {
            // redirectErrorStream = true 异常流重定向 2>&1
            Process process = (new ProcessBuilder(cmds)).redirectErrorStream(true).start();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String processId = null;
            while ((processId = reader.readLine()) != null) {
                result.add(processId);
            }
            result = 0 != process.waitFor() ? null : result;
        } catch (IOException | InterruptedException e) {
            result = null;
            e.printStackTrace();
        }

        return result;
    }
    /**
     * 获取执行命令进程的子进程ids(排除自己的pid)
     * @author 刘志新
     * @email lzxorz@163.com
     */
    public static List<String> getSubPids(List<String> runCommands, Process p) {
        final String pid = getPid(p);
        final List<String> pids = getPids(runCommands);
        return pids.stream().filter(id -> (null != id && !id.equals(pid))).collect(Collectors.toList());
    }

    /**
     *
     * @author 刘志新
     * @email  lzxorz@163.com
     */
    // public static boolean killAllProcesses(Process p) {
    //     if(!p.isAlive()){
    //         System.err.println("process not alive");
    //         return false;
    //     }
    //
    //     String pid = ProcessUtils.getPid(p);
    //     if (null == pid) {
    //         return false;
    //     }
    //
    //     boolean success = true;
    //     // 先杀掉子进程
    //     try {
    //         int exitcode = new ProcessBuilder("/usr/bin/pkill", "-9", "-P", pid).start().waitFor();
    //         success = 0 == exitcode;
    //     } catch (IOException | InterruptedException e) {
    //         success = false;
    //         e.printStackTrace();
    //     }
    //     // 再杀父进程
    //     if (success) {
    //         p.destroyForcibly();
    //     }
    //     return success;
    // }
    public static boolean killAllProcesses(List<String> runCommands) {
        boolean success = true;
        try {
            String[] cmds = {"/bin/sh", "-c", "ps -ef | grep \"" + String.join(" ", runCommands) + "\" | grep -v grep | awk '{ print $2 }' | xargs kill -9"};
            int exitcode = new ProcessBuilder(cmds).start().waitFor();
            success = 0 == exitcode;
        } catch (IOException | InterruptedException e) {
            success = false;
            e.printStackTrace();
        }
        return success;
    }
}
